BitTorrent: MagnetLink and BitTorrent Download
This module provides BT(BitTorrent) download resource function and supports adding download task through BT seed or magnet URL.
This module is provided in EdgerOS 2.2.10 and later.
User can use the following code to import the bittorrent module.
const { Session } = require('bittorrent');
Support
The following shows bittorrent module APIs available for each permissions.
| User Mode | Privilege Mode | |
|---|---|---|
| Session | ● | ● |
| session.addTorrent | ● | ● |
| session.rmTorrent | ● | ● |
| session.getTorrent | ● | ● |
| session.isPaused | ● | ● |
| session.pause | ● | ● |
| session.resume | ● | ● |
| session.start | ● | ● |
| session.stop | ● | ● |
| torrent.id | ● | ● |
| torrent.metadata | ● | ● |
| torrent.isFinish | ● | ● |
| torrent.isPaused | ● | ● |
| torrent.start | ● | ● |
| torrent.stop | ● | ● |
| torrent.pause | ● | ● |
| torrent.resume | ● | ● |
| torrent.clear | ● | ● |
| torrent.setPriorities | ● | ● |
| torrent.getFiles | ● | ● |
| torrent.save | ● | ● |
Session Class
new Session([params])
params{Object} Session params.- Returns: {Object} Session object.
Create a session object.
params includes:
persistence{Boolean} Save session state or not, default: false.sessionFile{String} Save session state file. Whenpersistenceis valid, this path will be used. default: '.session'.updatePeriod{Integer} (ms) session status update cycle. All requests in the session are responded to through status updates.default: 5000ms.maxUploads{Integer} the maximum number of peers that's unchoked at the same time on this torrent. default: -1, infinite.maxConnections{Integer} the maximum number of connection this torrent will open. If all connections are used up, incoming connections may be refused or poor connections may be closed. This must be at least 2. default: -1, unlimited.uploadLimit{Integer} (byte/s) limit the upload bandwidth used by this particular torrent to the limit you set. It is given as the number of bytes per second the torrent is allowed to upload. default: -1, unlimited.downloadLimit{Integer} (byte/s) limit the download bandwidth used by this particular torrent to the limit you set. It is given as the number of bytes per second the torrent is allowed to download. default: -1, unlimited.debug{Boolean} default: false Output debugging information or not.
Example
const session = new Session({ persistence: true, debug: true });
Session Object
session.addTorrent(params)
params{Object} Add torrent params.- Returns: promise object of
torrent: {Torrent} result.
Add torrent to session.
params includes:
torrentFile{String} seed file path of torrent.magnetUrl{String} magnet url of torrent.EithertorrentFileormagnetUrlmust be provided,torrentFileprioritymagnetUrl, if both are valid.torrentFiletakes priority overmagnetUrlif both are valid.persistence{Boolean} default: true. Ifpersistenceis enabled,resumeFileparam is effective. When adding a torrent to a session, if aresumeFilefile exists, the state of the torrent will be loaded. Otherwise, aresumeFilesfile will be created. When downloading a torrent, the state of the torrent will be saved.resumeFile{String} default: './<torrent_hash>.resume'. This param is valid whenpersistenceis enable. The state of the torrent will be loaded and saved to this file.savePath{String} default: '.'. Torrent data save to this file.maxUploads{Integer} the maximum number of peers that's unchoked at the same time on this torrent. default to session parammaxUploads.maxConnections{Integer} the maximum number of connection this torrent will open. If all connections are used up, incoming connections may be refused or poor connections may be closed. This must be at least 2. default to session parammaxConnections.uploadLimit{Integer} (byte/s) limit the upload bandwidth used by this particular torrent to the limit you set. It is given as the number of bytes per second the torrent is allowed to upload. default to session paramuploadLimit.downloadLimit{Integer} (byte/s) limit the download bandwidth used by this particular torrent to the limit you set. It is given as the number of bytes per second the torrent is allowed to download. default to session paramdownloadLimit.
Example
session.addTorrent({
persistence: true,
torrentFile: './ubuntu-24.10-desktop-amd64.iso.torrent'
})
.then(torrent => {
console.info('add torrent success:', torrent.id);
});
session.rmTorrent(idOrTorrent[, option])
idOrTorrent{String | Torrent} Torrent id or torrent object.option{Object} Remove torrent option.del{Boolean} default: false. Delete torrent data when remove torrent ifdelset totrue.
- Returns: promise object of torrent
id: {String} result.
Remove torrent to session.
Example
session.rmTorren(torrent, {
del: true
})
.then((id) => {
console.info('remove torrent success:', id);
});
session.getTorrent(id)
id{String} Torrent id.- Returns: {Torrent | undefined} Get torrent object if exist.
Get torrent object.
Example
var torrent = session.getTorrent('e2467cbf021192c241367b892230dc1e05c0580e');
session.isPause
- {Boolean}
Session is pause or not.
session.pause()
- Returns: {Boolean} success or not.
Pause session. Pausing the session has the same effect as pausing every torrent in it. Resuming will restore the torrents to their previous paused state. i.e. the session pause state is separate from the torrent pause state. A torrent is inactive if it is paused or if the session is paused.
Example
session.pause();
session.resume()
- Returns: {Boolean} success or not.
Resume session.
Example
session.resume();
session.start()
State session. Periodically update the torrents status, with the period specified by the updatePeriod param.
Example
session.start();
session.stop()
- Returns: promise object.
Stop all torrents, stop update torrents status.
Example
session.stop()
.then(() => {
console.info('session stop.');
});
Session Object Events
Session class inherit from EventEmitter, The following events are thrown in some specific situations.
error
Session error event.
Example
session.on('error', (err) => {
console.error(err.message);
session.stop();
});
Torrent Object
torrent.id
- {String}
Torrent id which is torrent's hash.
torrent.metadata
- {Object}
name{String} Torrent resource name.size{Integer} Torrent resource size(byte).files{Array} Torrent file object list.
Torrent metadata info. metadata value is null when torrent object create until metadata event is emited.
metadata file object include:
name{String} File name.size{Integer} File size(byte).priority{Integer} File download priority, detail to see:torrent.setPriorities.
If a torrent object is created from a seed file, metadata information will be parsed from the seed file; If the torrent object is created from a magnet URL, the torrent will retrieve metadata information from the downloaded metadata data.
torrent.isFinish()
Torrent is finished or not.
torrent.isPause()
Torrent is pause or resume。
torrent.start()
- Returns: {Boolean}
false- torrent state invalid.
Start torrent download, Torrent will turn to resume. Before starting, you should check the file download priority and set an appropriate priority.
Example
torrent.start();
torrent.stop([force])
force{Boolean} default: false. Ifforceis false, torrent will save state before stop.- Returns: promise object.
Stop torrent. It will call the session.rmTorrent interface to remove the torrent If the torrent has already started, it will trigger the stop event. Torrent stop will ultimately trigger the destroy event.
Example
torrent.stop()
.then(() => {
console.info('torrent stop.');
});
torrent.pause()
- Returns: {Boolean}
false- torrent state invalid.
Pause torrent. Torrent will notify status changes through the pause event.
Example
torrent.pause();
torrent.resume()
- Returns: {Boolean}
false- torrent state invalid.
Resume torrent. Torrent will notify status changes through the resume event.
Example
torrent.resume();
torrent.clear()
- Returns: {Boolean}
false- torrent state invalid.
If the torrent is in an error state, this will clear the error and start the torrent again.
torrent.setPriorities(priorities)
priorities{Array} priorities object array, object:index{Integer} the file index, range [0 - max_file_index]. File index order the save astorrent.metadata.files.prio{Integer} the file download priority.The enumeration value is defined bybittorrent.PRIO.
- Returns: {Boolean} Set priorities success or not. This api will throw error if argument error.
bittorrent.PRIO defined:
DONT: Don't download the file. Partial pieces may still be downloaded when setting file priorities.DEFAULT: The default priority for files.LOW: The lowest priority for files.TOP: The highest priority for files.
Set torrent file priorities. The priority is set by default(DEFAULT) when creating a torrent. Setting the file priority to DONT can abort the download of the file. When the file priority changes, the torrent object will emit the priority event.
Example
const { PRIO } = require('bittorrent');
torrent.setPriorities({ 0, PRIO.DONT });
torrent.getFiles()
- Returns: promise object of
files{Array}, array item {Object}:name{String} File name.size{Integer} File total size(byte).priority{Integer} File download priority, detail to see:torrent.setPriorities.download{Integer} Downloaded size(byte).progress{Float} File progress[0-1]rate{Integer} payload download real time rate(byte/s). This rate is calculated based on the simulated value obtained from each query download data statistics.
Get torrent files attribute.
Example
torrent.getFiles()
.then((files) => {
console.info('torrent files:', JSON.stringify(files));
});
save([force])
force{Boolean} Force save or not. default: false- Returns: promise object.
Save torrent state if the persistence param is enabled when adding a torrent. Torrent automatically saves state periodically, and users generally do not need to call save().
This method is reentrant. When the force is true, the torrent will submit a new save request whether the previous save request has been completed or not. When the force is false, do not resubmit the save request if there are previous unfinished save requests.
Example
torrent.save(true)
.then(() => {
console.info('torrent state save success.');
});
Torrent Object Events
Torrent class inherit from EventEmitter, The following events are thrown in some specific situations.
metadata
metadata{Object}name{String} Torrent resource name.size{Integer} Torrent resource size(byte).files{Array} Torrent file object list.
metadata file object include:
name{String} File name.size{Integer} File size(byte).priority{Integer} File download priority, detail to see:torrent.setPriorities.
This event occurred during torrent parsed or downloaded metadata data. The torrent ready to download payload after metadata event, call torrent.start() to start downloading data.
Example
torrent.on('metadata', (metadata) => {
console.info('torrent metadata: ', JSON.stringify(metadata));
});
puase
Torrent paused.
resume
Torrent resumed.
finish
Torrent data download completed.
Example
torrent.on('finish', () => {
console.info('torrent finish:', torrent.id);
});
stop
Torrent stopped. This event will only be triggered when the torrent is stopped after it has successfully started. Torrent prohibits all activities.
torrent.stop or session.rmTorrent will trigger this event.
destroy
Torrent destroy. When the torrent is stopped or removed from the session, this event will be triggered when the torrent is successfully destroyed. This event is the last event of torrent, after which the task activity will be invalid.
priority
priorities{Array} item index the same as torrent files index. item value defined byTorrent.PRIO, detail to see:torrent.setPriorities.
This event occurred when torrent files priorities change. metadata.files` priorities are updated synchronously.
Example
torrent.on('priority', (priorities) => {
console.info('torrent change priorities: ', JSON.stringify(priorities));
});
update
status{Object}state{String} the main state the torrent is in.total_download{Integer} the number of bytes downloaded to all peers, accumulated, this session only. The session is considered to restart when a torrent is paused and restarted again. When a torrent is paused, these counters are reset to 0. If you want complete, persistent, stats, see all_time_download.total_payload_download{Integer} counts the amount of bytes received this session, but only the actual payload data (i.e the interesting data), these counters ignore any protocol overhead. The session is considered to restart when a torrent is paused and restarted again. When a torrent is paused, these counters are reset to 0.total_done{Integer} the total number of bytes of the file(s) that we have. All this does not necessarily has to be downloaded during this session (that's total_payload_download).total{Integer} the total number of bytes to download for this torrent. This may be less than the size of the torrent in case there are pad files. This number only counts bytes that will actually be requested from peers.total_wanted_done{Integer} the number of bytes we have downloaded, only counting the pieces that we actually want to download. i.e. excluding any pieces that we have but have priority 0 (i.e. not wanted). Once a torrent becomes seed, any piece- and file priorities are forgotten and all bytes are considered "wanted".total_wanted{Integer} The total number of bytes we want to download. This may be smaller than the total torrent size in case any pieces are prioritized to 0, i.e. not wanted. Once a torrent becomes seed, any piece- and file priorities are forgotten and all bytes are considered "wanted".all_time_download{Integer} are accumulated download payload byte counters. They are saved in and restored from resume data to keep totals across sessions.progress{Integer} a value in the range [0, 1], that represents the progress of the torrent's current task. It may be checking files or downloading.progress_ppm{Integer} progress parts per million (progress * 1000000) when disabling floating point operations, this is the only option to query progress. reflects the same value as progress, but instead in a range [0, 1000000] (ppm = parts per million). When floating point operations are disabled, this is the only alternative to the floating point value in progress.download_rate{Integer} the total rates for all peers for this torrent. The rates are given as the number of bytes per second.download_payload_rate{Integer} the total transfer rate of payload only, not counting protocol chatter. This might be slightly smaller than the other rates, but if projected over a long time (e.g. when calculating ETA:s) the difference may be noticeable.num_seeds{Integer} the number of peers that are seeding that this client is currently connected to.num_peers{Integer} the number of peers this torrent currently is connected to.is_seeding{Boolean} true if all pieces have been downloaded.is_finished{Boolean} true if all pieces that have a priority > 0 are downloaded. There is only a distinction between finished and seeding if some pieces or files have been set to priority 0, i.e. are not downloaded.has_metadata{Boolean} true if this torrent has metadata (either it was started from a .torrent file or the metadata has been downloaded).has_incoming{Boolean} true if there has ever been an incoming connection attempt to this torrent.need_save_resume{Boolean} true if this torrent has unsaved changes to its download state and statistics since the last resume data was saved.announcing_to_trackers,announcing_to_lsd,announcing_to_dht{Boolean} these are set to true if this torrent is allowed to announce to the respective peer source. Whether they are true or false is determined by the queue logic/auto manager. Torrents that are not auto managed will always be allowed to announce to all peer sources.hash{String} torrent hash string.
Torrent downloading status. This event is triggered by session update states, see (updatePeriod)[## new Session([params])].
Example
torrent.on('update', (status) => {
console.info('torrent on status:', JSON.stringify(status));
});
/* result em:
{
"state": "downloading",
"total_download": 0,
"total_payload_download": 0,
"total_done": 117161984,
"total": 5665497088,
"total_wanted_done": 117161984,
"total_wanted": 5665497088,
"all_time_download": 117161984,
"progress": 0.02067900076508522,
"progress_ppm": 20679,
"download_rate": 0,
"download_payload_rate": 0,
"num_seeds": 0,
"num_peers": 0,
"is_seeding": false,
"is_finished": false,
"has_metadata": true,
"has_incoming": false,
"need_save_resume": false,
"announcing_to_trackers": true,
"announcing_to_lsd": true,
"announcing_to_dht": true,
"hash": "3f9aac158c7de8dfcab171ea58a17aabdf7fbc93"
} */
error
Torrent error event.
Example
torrent.on('error', (err) => {
console.error('torrent error:', err.message);
session.rmTorrent(torrent);
});
Example
const { Session, PRIO } = require('bittorrent');
const session = new Session({ persistence: true });
session.addTorrent({
persistence: true,
magnetUrl: 'magnet:?xt=urn:btih:ZOCMZQIPFFW7OLLMIC5HUB6BPCSDEOQU'
})
.then(torrent => {
console.info('add torrent success:', torrent.id);
/*
* get metadata info, choose download files and start download.
*/
torrent.on('metadata', (metadata) => {
console.info('torrent metadata: ', JSON.stringify(metadata));
/*
* download all files: set all files priority to default.
*/
let prios = [];
metadata.files.forEach((file, index) => {
if (file.priority === PRIO.DONT) {
prios.push({ index, prio: PRIO.DEFAULT });
}
});
if (prios.length > 0) {
torrent.setPriorities(prios);
}
/*
* start torrent(or stop on this point while recv metadata)
*/
torrent.start();
/*
* get files progress period(can also reset files priority on downloading)
*/
setTimeout(_ => {
torrent.getFiles()
.then(info => {
console.info('torrent files: ', JSON.stringify(info));
})
.catch(err => console.warn(err.message));
}, 10000);
});
torrent.on('finish', () => {
console.info('torrent finish:', torrent.id);
});
torrent.on('destroy', () => {
console.info('torrent destroy:', torrent.id);
});
torrent.on('error', (err) => {
console.error('torrent error:', err.message);
session.rmTorrent(torrent);
});
torrent.on('update', (status) => {
console.info('torrent on status:', JSON.stringify(status));
});
})
.catch(err => {
console.error('add torrent fail:', err.message);
});
session.start();
require('iosched').forever();




陕公网安备61019002002605号